﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.IO;
using System.IO.IsolatedStorage;
using System.Diagnostics;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Shapes;

using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;

using Microsoft.Windows.Controls;
using Microsoft.Windows.Controls.Primitives;

namespace BadHabit.Factory {

    /// <summary>
    /// Generic helper class to help here and then.
    /// </summary>
    public class Helper {



        public static BitmapSource ToBitmapSource(System.Drawing.Bitmap bitmap) {
            System.IO.MemoryStream stream = new MemoryStream();
            bitmap.Save(stream, System.Drawing.Imaging.ImageFormat.Png);
            stream.Position = 0;

            var result = BitmapFrame.Create(stream, BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
            result.Freeze();
            return result;
            
        }


        public static bool IsArrayEqual(object[] a1, object[] a2) {
            if (a1.Length != a2.Length)
                return false;
            for (int i = 0; i < a1.Length; i++)
                if (!a1[i].Equals(a2[i]))
                    return false;

            return true;
        }

        /// <summary>
        /// Return the typed row from a row view.
        /// </summary>
        /// <typeparam name="T">The type of the row</typeparam>
        /// <param name="dataContext">The row view</param>
        /// <returns>The typed row</returns>
        public static T GetRowFromRowView<T>(object dataContext) {
            if (dataContext == null)
                return default(T);
            System.Data.DataRowView rowView = dataContext as System.Data.DataRowView;
            if (rowView == null)
                return default(T);
            return (T)(object)rowView.Row;
        }
        
        /// <summary>
        /// Open OS Window.
        /// </summary>
        /// <param name="processPath"></param>
        public static void OpenOSWindow(string processPath) {
            try {
                System.Diagnostics.Process.Start(processPath);
            } catch (Exception) {
                Windows.Error.ShowAlert("Sorry, could not open file.\n" + processPath);
            }
        }

        public static void LogError(Exception ex) {

            IsolatedStorageFile isoStore = IsolatedStorageFile.GetStore(IsolatedStorageScope.User |
        IsolatedStorageScope.Assembly | IsolatedStorageScope.Domain, null, null);

            IsolatedStorageFileStream oStream = new IsolatedStorageFileStream("factoryErrorLog.txt", FileMode.Append, FileAccess.Write, isoStore);

            StreamWriter writer = new StreamWriter(oStream);
            writer.WriteLine(DateTime.Now);
            writer.WriteLine(ex.Message);
            writer.WriteLine(ex.StackTrace.ToString());
            writer.WriteLine("------------------------------------------------------------------------------");
            writer.Close();

        }

        public static bool IsMovementBigEnough(Point initialMousePosition, Point currentPosition) {
            return (Math.Abs(currentPosition.X - initialMousePosition.X) >= SystemParameters.MinimumHorizontalDragDistance ||
                 Math.Abs(currentPosition.Y - initialMousePosition.Y) >= SystemParameters.MinimumVerticalDragDistance);
        }

      
        public static T GetObjectOfTypeInVisualTree<T>(System.Windows.DependencyObject dpob) where T : System.Windows.DependencyObject {
            int count = System.Windows.Media.VisualTreeHelper.GetChildrenCount(dpob);
            for (int i = 0; i < count; i++) {
                System.Windows.DependencyObject child = System.Windows.Media.VisualTreeHelper.GetChild(dpob, i);
                T childAsT = child as T;
                if (childAsT != null) {
                    return childAsT;
                }
                childAsT = GetObjectOfTypeInVisualTree<T>(child);
                if (childAsT != null) {
                    return childAsT;
                }
            }
            return null;
        }

        

        public static T FindVisualParent<T>(UIElement element) where T : UIElement {
            UIElement parent = element;
            while (parent != null) {
                T correctlyTyped = parent as T;
                if (correctlyTyped != null) {
                    return correctlyTyped;
                }

                
                parent = VisualTreeHelper.GetParent(parent) as UIElement;
            }
            return null;
        }

        public static DataGridCell GetCell(DataGrid datagrid, int row, int column) {
            datagrid.UpdateLayout();
            DataGridRow rowContainer = GetRow(datagrid, row);

            if (rowContainer == null)
                return null;
    
            DataGridCellsPresenter presenter = GetObjectOfTypeInVisualTree<DataGridCellsPresenter>(rowContainer);

            // try to get the cell but it may possibly be virtualized
            DataGridCell cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(column);
            if (cell == null) {
                // now try to bring into view and retreive the cell
                datagrid.ScrollIntoView(rowContainer, datagrid.Columns[column]);
                
                cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(column);
            }
            return cell;
        }





        public static DataGridRow GetRow(DataGrid datagrid, int index) {
            if (index < 0)
                return null;
            DataGridRow row = (DataGridRow)datagrid.ItemContainerGenerator.ContainerFromIndex(index);
            if (row == null) {
                // may be virtualized, bring into view and try again
                datagrid.ScrollIntoView(datagrid.Items[index]);
                row = (DataGridRow)datagrid.ItemContainerGenerator.ContainerFromIndex(index);
            }
            return row;
        }


        // Walks up the tree starting at the bottomMostVisual, until it finds the first item container for the ItemsControl
        // passed as a parameter.
        // In order to make sure it works with any control that derives from ItemsControl, this method makes no assumption 
        // about the type of that container.(it will get a ListBoxItem if it's a ListBox, a ListViewItem if it's a ListView...)
        public static FrameworkElement GetItemContainer(ItemsControl itemsControl, Visual bottomMostVisual) {
            FrameworkElement itemContainer = null;
            if (itemsControl != null && bottomMostVisual != null && itemsControl.Items.Count >= 1) {
                var firstContainer = itemsControl.ItemContainerGenerator.ContainerFromIndex(0);
                if (firstContainer != null) {
                    Type containerType = firstContainer.GetType();

                    itemContainer = FindAncestor(containerType, bottomMostVisual);

                    // Make sure that the container found belongs to the items control passed as a parameter.
                    if (itemContainer != null && itemContainer.DataContext != null) {
                        FrameworkElement itemContainerVerify = itemsControl.ItemContainerGenerator.ContainerFromItem(itemContainer.DataContext) as FrameworkElement;
                        if (itemContainer != itemContainerVerify) {
                            itemContainer = null;
                        }
                    }
                }
            }
            return itemContainer;
        }

        public static FrameworkElement FindAncestor(Type ancestorType, Visual visual) {
            while (visual != null && !ancestorType.IsInstanceOfType(visual)) {
                visual = (Visual)VisualTreeHelper.GetParent(visual);
            }
            return visual as FrameworkElement;
        }
    


    }
}
